﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Collections;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
    }

    public class RecursiveFileSearch
    {
        
        public struct RecnikFajl
        {
            public string Kljuc;
            public uint VelicinaFajla;
            public string Putanja;

            public RecnikFajl(string a, uint b, string c)
            {
                Kljuc = a;
                VelicinaFajla = b;
                Putanja = c;
            }

            string vratiKljuc(RecnikFajl a)
            {
                return a.Kljuc;
            }

            uint vratiVelicinu(RecnikFajl a)
            {
                return a.VelicinaFajla;
            }

            string vratiPutanju(RecnikFajl a)
            {
                return a.Putanja;
            }
        }

        public static List<RecnikFajl> ListaFajlova = new List<RecnikFajl>();
        
        static System.Collections.Specialized.StringCollection log = new System.Collections.Specialized.StringCollection();
        
        static System.Collections.Specialized.StringCollection dugackiFajlovi = new System.Collections.Specialized.StringCollection();


        static System.Collections.Specialized.StringCollection dupikatiZaFajl = new System.Collections.Specialized.StringCollection();

        static void Main()
        {

            //Console.ReadKey();
            //Dictionary<string,Fajl> ListaFajlova = new Dictionary<string,Fajl>();
            /*ArrayList a1 = new ArrayList();
            Stopwatch stop = new Stopwatch();
            stop.Start();
            Console.WriteLine(stop.ElapsedMilliseconds.ToString());
            int max = 10000000;
            for (int i = 0; i < max; i++)
            a1.Add(i);
            Console.WriteLine(stop.ElapsedMilliseconds.ToString());
            List<int> a2 = new List<int>();
            for (int i = 0; i < max; i++)
            a2.Add(i);
            Console.WriteLine(stop.ElapsedMilliseconds.ToString());
            Console.ReadKey();*/
            // Start with drives if you have to search the entire computer. 
            string[] drives = System.Environment.GetLogicalDrives();

            foreach (string dr in drives)
            {
                System.IO.DriveInfo di = new System.IO.DriveInfo(dr);

                // Here we skip the drive if it is not ready to be read. This 
                // is not necessarily the appropriate action in all scenarios. 
                if (!di.IsReady)
                {
                    Console.WriteLine("The drive {0} could not be read", di.Name);
                    continue;
                }
                System.IO.DirectoryInfo rootDir = di.RootDirectory;
                Console.WriteLine("Trcanje kroz Direktorijume");
                //Console.ReadKey();
                WalkDirectoryTree(rootDir);
                try
                {
                    int brojFajlova = ListaFajlova.Count();
                    Console.WriteLine(brojFajlova);
                }
                catch (OverflowException)
                {
                    Console.WriteLine("The count is too large to store as an Int32.");
                    Console.WriteLine("Try using the LongCount() method instead.");
                }
            }

            // Write out all the files that could not be processed.
            Console.WriteLine("Files with restricted access:");
            Console.WriteLine("Press any key");
            Console.ReadKey();
            foreach (string s in log)
            {
                Console.WriteLine(s);
            }
            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key");
            Console.ReadKey();
           
            Console.WriteLine("Dugacki fajlovi i sranja");
            Console.WriteLine("Press any key");
            Console.ReadKey();
            foreach (string s in dugackiFajlovi)
            {
                Console.WriteLine(s);
            }
            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key");
            Console.ReadKey();

            int broj = ListaFajlova.Count();
            Console.WriteLine(broj);
            Console.WriteLine("Sledi ispis/pretraga - stisni anykey");
            Console.ReadKey();

            //ListaFajlova.Sort();
            int prekidac = 0;
            foreach (RecnikFajl rf in ListaFajlova)
            {
                string kljuc1 = rf.Kljuc;
                foreach (RecnikFajl df in ListaFajlova)
                {
                    if (rf.Kljuc == df.Kljuc)
                    {
                        if (rf.Putanja != df.Putanja)
                        {
                            if (rf.VelicinaFajla >= 10000000)
                            {
                                prekidac++;
                                Console.Write(prekidac);
                                //Console.Write("Fajl na putanji ima brata blizanca");
                                //Console.WriteLine(rf.Putanja);
                                dupikatiZaFajl.Add(rf.Putanja);
                                //Console.Write("Blizanac: ");
                                //Console.WriteLine(df.Putanja);
                                dupikatiZaFajl.Add(df.Putanja);
                                //ListaFajlova.Remove(df);
                                if (prekidac >= 500)
                                {
                                    break;
                                }
                            }
                            if (prekidac >= 500)
                            {
                                break;
                            }
                        }
                        if (prekidac >= 500)
                        {
                            break;
                        }
                    }
                        if (prekidac >= 500)
                    {
                        break;
                    }
                }
                if (prekidac >= 500)
                {
                    break;
                }
                //Console.WriteLine(rf.Kljuc);
                //Console.WriteLine(rf.VelicinaFajla);
                //Console.WriteLine(rf.Putanja);
            }
            

            
            foreach (string s in dupikatiZaFajl)
            {
                string temps = s + "\r\n";
                File.AppendAllText(@"C:\test1\test.txt", temps);
            }

        }

        static void WalkDirectoryTree(System.IO.DirectoryInfo root)
        {
            System.IO.FileInfo[] files = null;
            System.IO.DirectoryInfo[] subDirs = null;

            // First, process all the files directly under this folder 
            try
            {
                files = root.GetFiles("*.*");
            }
            // This is thrown if even one of the files requires permissions greater 
            // than the application provides. 
            catch (UnauthorizedAccessException e)
            {
                // This code just writes out the message and continues to recurse. 
                // You may decide to do something different here. For example, you 
                // can try to elevate your privileges and access the file again.
                log.Add(e.Message);
            }

            catch (System.IO.DirectoryNotFoundException e)
            {
                Console.WriteLine(e.Message);
            }

            if (files != null)
            {
                foreach (System.IO.FileInfo fi in files)
                {
                    // In this example, we only access the existing FileInfo object. If we 
                    // want to open, delete or modify the file, then 
                    // a try-catch block is required here to handle the case 
                    // where the file has been deleted since the call to TraverseTree().
                    string a = "";
                    uint b = 0;
                    string c = "";
                    /*Console.Write(fi.Name);
                    Console.Write(" - ");
                    Console.WriteLine(fi.Length);*/
                    
                    try
                    {
                        a = fi.Name + fi.Length; //kljuc
                        b = (uint)Convert.ToDouble(fi.Length); //velicina fajla
                        c = fi.FullName; //putanja
                    }
                    catch (PathTooLongException e)
                    {
                        string aexp = e.Message + fi.Name;
                        dugackiFajlovi.Add(aexp); 
                    }
                    RecnikFajl a1 = new RecnikFajl(a,b,c);
                    //Console.ReadKey();
                    ListaFajlova.Add(a1);
                    //Console.Write(".");
                }

                // Now find all the subdirectories under this directory.
                subDirs = root.GetDirectories();

                foreach (System.IO.DirectoryInfo dirInfo in subDirs)
                {
                    // Resursive call for each subdirectory.
                    WalkDirectoryTree(dirInfo);
                }
            }
        }
    }
}